package jtwittconsolepackage;

/**
 *
 * Reads the configuration file.
 */
import jTwittConsoleExceptions.IJTwittConsoleErrorTypes;
import jTwittConsoleExceptions.KeyValueTooShort;
import java.io.File;
import java.io.FileNotFoundException;
import org.w3c.dom.*;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;

/**
 * The class ConfigReader reads the configuration information from an xml file
 * and keeps the information. Via 'get' methods the information can be accessed.
 */
public class ConfigReader implements IJTwittConsoleErrorTypes
{
    //debugg-session?
    //boolean debug = false;

    private static ConfigReader configReaderInstance = null;
    //keys
    private char refreshKey;
    private char newMessageKey;
    private char quitKey;
    private char helpKey;
    private char mentionKey;
    private char searchKey;
    private char retweetKey;
    private char favoriteKey; //favorites one tweet
    private char favoriteListKey; //get the list of favorite tweets 

    public char getFavoriteListKey()
    {
        return favoriteListKey;
    }

    public static ConfigReader getInstance()
    {
        if (configReaderInstance == null)
        {
            configReaderInstance = new ConfigReader();
        }

        return configReaderInstance;
    }

    /**
     * Function readConfigFile reads the information from an xml file and stores
     * them locally. It is possible to use the "debug" variable to change between
     * normal and debugging mode.
     */
    public void readConfigFile()
    {
        try
        {
            DocumentBuilderFactory docBuilderFactory =
                    DocumentBuilderFactory.newInstance();
            DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();

            File configFile = new File("config.xml");//no debugging

            //no config file found
            if (configFile.exists() == false)
            {
                throw new FileNotFoundException();
            }

            Document doc = docBuilder.parse(configFile);

            //normalize text representation
            doc.getDocumentElement().normalize();

            //reading the key information
            NodeList configElementsList = doc.getElementsByTagName("keyConfig");


            //the node
            Node node = configElementsList.item(0);

            //read all keys
            refreshKey = readSpecificConfigKey("refreshKey", node);
            newMessageKey = readSpecificConfigKey("newMessageKey", node);
            quitKey = readSpecificConfigKey("quitKey", node);
            helpKey = readSpecificConfigKey("helpKey", node);
            mentionKey = readSpecificConfigKey("mentionKey", node);
            searchKey = readSpecificConfigKey("searchKey", node);
            retweetKey = readSpecificConfigKey("retweetKey", node);
            favoriteKey = readSpecificConfigKey("favoriteKey", node);
            favoriteListKey = readSpecificConfigKey("favoriteListKey", node);

            //for debugging
            /*System.out.println("refreshKey: " + refreshKey);
            System.out.println("newMessageKey: " + newMessageKey);*/

        }
        catch (FileNotFoundException fnfe)
        {
            ErrorLogger.getInstance().exceptionOccured("An error occured while"
                    + " reading the config file: No config file was found.",
                    "-1", fnfe, errorCodeReadConfigFileFileNotFound);
        }
        catch (KeyValueTooShort kvts)
        {
            ErrorLogger.getInstance().exceptionOccured("An error occured while"
                    + " reading the config file: Configured key malformed.",
                    "-1", kvts, errorCodeReadConfigFileKeyValueNull, kvts.keyToRead);
        }
        catch (Exception e)
        {
            ErrorLogger.getInstance().exceptionOccured("An error occured while"
                    + " reading the config file.",
                    "-1", e, errorCodeReadConfigFile);
        }
    }

    public char getFavoriteKey()
    {
        return favoriteKey;
    }

    public char getRetweetKey()
    {
        return retweetKey;
    }

    /**
     * The function reads a specific key from the config file.
     * @param keyToRead the key that has to be read from the file.
     * @param node a node within the config file.
     * @return the char value for the configured key.
     */
    private char readSpecificConfigKey(String keyToRead, Node node)
            throws KeyValueTooShort
    {
        char result;

        //needed for parsing the xml file
        Element element;
        NodeList nodeList;
        Element fstNmElmnt;
        NodeList fstNm;

        //reading twitterID
        element = (Element) node;
        nodeList = element.getElementsByTagName(keyToRead);
        fstNmElmnt = (Element) nodeList.item(0);
        fstNm = fstNmElmnt.getChildNodes();
        result = ((Node) fstNm.item(0)).getNodeValue().charAt(0);

        //key value was to short -> Exception
        char[] charArray = new char[]
        {
            new Character(result)
        };
        if (charArray.length < 1)
        {
            throw new KeyValueTooShort(keyToRead);
        }

        return result;
    }

    public char getRefreshKey()
    {
        return this.refreshKey;
    }

    public char getNewMessageKey()
    {
        return this.newMessageKey;
    }

    public char getQuitKey()
    {
        return this.quitKey;
    }

    public char getHelpKey()
    {
        return this.helpKey;
    }

    public char getMentionKey()
    {
        return this.mentionKey;
    }

    public char getSearchKey()
    {
        return this.searchKey;
    }
}
